home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / pbmplus / pgm / pgmnorm.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  5KB  |  183 lines

  1. /* pgmnorm.c - read a portable graymap and normalize the contrast
  2. **
  3. ** Copyright (C) 1989, 1991 by Jef Poskanzer.
  4. **
  5. ** Permission to use, copy, modify, and distribute this software and its
  6. ** documentation for any purpose and without fee is hereby granted, provided
  7. ** that the above copyright notice appear in all copies and that both that
  8. ** copyright notice and this permission notice appear in supporting
  9. ** documentation.  This software is provided "as is" without express or
  10. ** implied warranty.
  11. */
  12.  
  13. #include "pgm.h"
  14.  
  15. static int hist[PGM_MAXMAXVAL+1];
  16.  
  17. void
  18. main( argc, argv )
  19. int argc;
  20. char* argv[];
  21.     {
  22.     FILE* ifp;
  23.     gray maxval;
  24.     gray** grays;
  25.     gray* grayrow;
  26.     register gray* gP;
  27.     int argn, rows, cols, format, row;
  28.     register int col;
  29.     int i, size, cutoff, count, val;
  30.     float bpercent, wpercent;
  31.     int bvalue, wvalue, range;
  32.     int specbpercent, specbvalue, specwpercent, specwvalue;
  33.     char* usage = "[-bpercent N | -bvalue N] [-wpercent N | -wvalue N] [pgmfile]";
  34.  
  35.     pgm_init( &argc, argv );
  36.  
  37.     argn = 1;
  38.     bpercent = 2.0;
  39.     wpercent = 1.0;
  40.     specbpercent = specbvalue = specwpercent = specwvalue = 0;
  41.  
  42.     while ( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' )
  43.     {
  44.     if ( pm_keymatch( argv[argn], "-bpercent", 3 ) )
  45.         {
  46.         if ( specbvalue )
  47.         pm_error( "only one of -bpercent and -bvalue may be specified" );
  48.         ++argn;
  49.         if ( argn == argc || sscanf( argv[argn], "%f", &bpercent ) != 1 )
  50.         pm_usage( usage );
  51.         if ( bpercent < 0.0  || bpercent > 100.0 )
  52.         pm_error( "black percentage must between 0 and 100" );
  53.         specbpercent = 1;
  54.         }
  55.     else if ( pm_keymatch( argv[argn], "-bvalue", 3 ) )
  56.         {
  57.         if ( specbpercent )
  58.         pm_error( "only one of -bpercent and -bvalue may be specified" );
  59.         ++argn;
  60.         if ( argn == argc || sscanf( argv[argn], "%d", &bvalue ) != 1 )
  61.         pm_usage( usage );
  62.         if ( bvalue < 0 )
  63.         pm_error( "black value must be >= 0" );
  64.         specbvalue = 1;
  65.         }
  66.     else if ( pm_keymatch( argv[argn], "-wpercent", 3 ) )
  67.         {
  68.         if ( specwvalue )
  69.         pm_error( "only one of -wpercent and -wvalue may be specified" );
  70.         ++argn;
  71.         if ( argn == argc || sscanf( argv[argn], "%f", &wpercent ) != 1 )
  72.         pm_usage( usage );
  73.         if ( wpercent < 0.0 || wpercent > 100.0 )
  74.         pm_error( "white percentage must be between 0 and 100" );
  75.         specwpercent = 1;
  76.         }
  77.     else if ( pm_keymatch( argv[argn], "-wvalue", 3 ) )
  78.         {
  79.         if ( specwpercent )
  80.         pm_error( "only one of -wpercent and -wvalue may be specified" );
  81.         ++argn;
  82.         if ( argn == argc || sscanf( argv[argn], "%d", &wvalue ) != 1 )
  83.         pm_usage( usage );
  84.         if ( wvalue < 0 )
  85.         pm_error( "white value must be >= 0" );
  86.         specwvalue = 1;
  87.         }
  88.     else
  89.         pm_usage( usage );
  90.     ++argn;
  91.     }
  92.  
  93.     if ( argn < argc )
  94.     {
  95.     ifp = pm_openr( argv[argn] );
  96.     ++argn;
  97.     }
  98.     else
  99.     ifp = stdin;
  100.  
  101.     if ( argn != argc )
  102.     pm_usage( usage );
  103.  
  104.     if ( specbvalue && specwvalue )
  105.     {
  106.     /* Rescale so that bvalue maps to 0, wvalue maps to maxval. */
  107.     pgm_readpgminit( ifp, &cols, &rows, &maxval, &format );
  108.     grayrow = pgm_allocrow( cols );
  109.     pgm_writepgminit( stdout, cols, rows, maxval, 0 );
  110.     for ( i = 0; i <= bvalue; ++i )
  111.         hist[i] = 0;
  112.     for ( i = wvalue; i <= maxval; ++i )
  113.         hist[i] = maxval;
  114.     range = wvalue - bvalue;
  115.     for ( i = bvalue+1, val = maxval; i < wvalue; ++i, val += maxval )
  116.         hist[i] = val / range;
  117.     for ( row = 0; row < rows; ++row )
  118.         {
  119.         pgm_readpgmrow( ifp, grayrow, cols, maxval, format );
  120.         for ( col = 0, gP = grayrow; col < cols; ++col, ++gP )
  121.         *gP = hist[*gP];
  122.         pgm_writepgmrow( stdout, grayrow, cols, maxval, 0 );
  123.         }
  124.     pm_close( ifp );
  125.     }
  126.     else
  127.     {
  128.     grays = pgm_readpgm( ifp, &cols, &rows, &maxval );
  129.     pm_close( ifp );
  130.  
  131.     /* Build histogram. */
  132.     for ( i = 0; i <= maxval; ++i )
  133.         hist[i] = 0;
  134.     for ( row = 0; row < rows; ++row )
  135.         for ( col = 0, gP = grays[row]; col < cols; ++col, ++gP )
  136.         ++hist[*gP];
  137.     size = rows * cols;
  138.     if ( ! specbvalue )
  139.         { /* Compute bvalue from bpercent. */
  140.         cutoff = size * bpercent / 100.0;
  141.         count = 0;
  142.         for ( bvalue = 0; bvalue <= maxval; ++bvalue )
  143.         {
  144.         count += hist[bvalue];
  145.         if ( count > cutoff )
  146.         break;
  147.         }
  148.         }
  149.     if ( ! specwvalue )
  150.         { /* Compute wvalue from wpercent. */
  151.         cutoff = size * wpercent / 100.0;
  152.         count = 0;
  153.         for ( wvalue = maxval; wvalue >= 0; wvalue-- )
  154.         {
  155.         count += hist[wvalue];
  156.         if ( count > cutoff )
  157.             break;
  158.         }
  159.         }
  160.  
  161.     /* Now rescale so that bvalue maps to 0, wvalue maps to maxval. */
  162.     pm_message(
  163.         "remapping %d..%d to %d..%d", bvalue, wvalue, 0, maxval, 0 );
  164.     pgm_writepgminit( stdout, cols, rows, maxval, 0 );
  165.     for ( i = 0; i <= bvalue; ++i )
  166.         hist[i] = 0;
  167.     for ( i = wvalue; i <= maxval; ++i )
  168.         hist[i] = maxval;
  169.     range = wvalue - bvalue;
  170.     for ( i = bvalue + 1, val = maxval; i < wvalue; ++i, val += maxval )
  171.         hist[i] = val / range;
  172.     for ( row = 0; row < rows; ++row )
  173.         {
  174.         for ( col = 0, gP = grays[row]; col < cols; ++col, ++gP )
  175.         *gP = hist[*gP];
  176.         pgm_writepgmrow( stdout, grays[row], cols, maxval, 0 );
  177.         }
  178.     }
  179.  
  180.     pm_close( stdout );
  181.     exit( 0 );
  182.     }
  183.